package com.fmdj.odr.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpException;
import cn.hutool.json.JSONObject;
import com.alibaba.druid.support.json.JSONUtils;
import com.fmdj.common.util.CommonResult;
import com.fmdj.common.util.PageUtils;
import com.fmdj.common.wxpay.MyWXPayConfig;
import com.fmdj.common.wxpay.WXPayUtil;
import com.fmdj.odr.controller.form.*;
import com.fmdj.odr.db.dao.OrderDao;
import com.fmdj.odr.db.pojo.OrderBillEntity;
import com.fmdj.odr.db.pojo.OrderEntity;
import com.fmdj.odr.service.OrderService;
import io.micrometer.core.instrument.search.Search;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/order")
@Tag(name = "OrderController", description = "订单模块接口")
@Slf4j
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private MyWXPayConfig wxPayConfig;

    @PostMapping("/selectDriverTodayBusinessData")
    @Operation(summary = "查询司机今日营业数据接口")
    public CommonResult selectDriverTodayBusinessData(@RequestBody @Valid SelectDriverTodayBusinessDataForm form) {
        HashMap hashMap = orderService.selectDriverTodayBusinessData(form.getDriverId());
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, hashMap);
    }

    @PostMapping("/insertOrder")
    @Operation(summary = "乘客下单")
    public CommonResult insertOrder(@RequestBody @Valid InsertOrderForm form) {

        //保存订单信息
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setUuid(form.getUuid());
        orderEntity.setCustomerId(form.getCustomerId());
        orderEntity.setStartPlace(form.getStartPlace());
        //设置经纬度 创建json对象保存经纬度再保存进实体中
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.set("latitude", form.getStartPlaceLatitude());
        jsonObject1.set("longitude", form.getStartPlaceLongitude());
        orderEntity.setStartPlaceLocation(jsonObject1.toString());
        orderEntity.setEndPlace(form.getEndPlace());
        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.set("latitude", form.getEndPlaceLatitude());
        jsonObject2.set("longitude", form.getEndPlaceLongitude());
        orderEntity.setEndPlaceLocation(jsonObject2.toString());
        orderEntity.setExpectsMileage(new BigDecimal(form.getExpectsMileage()));
        orderEntity.setExpectsFee(new BigDecimal(form.getExpectsFee()));
        orderEntity.setFavourFee(new BigDecimal(form.getFavourFee()));
        orderEntity.setCarPlate(form.getCarPlate());
        orderEntity.setCarType(form.getCarType());
        orderEntity.setDate(form.getDate());
        orderEntity.setChargeRuleId(form.getChargeRuleId());

        //保存账单信息
        OrderBillEntity orderBillEntity = new OrderBillEntity();
        orderBillEntity.setBaseMileage(form.getBaseMileage());
        orderBillEntity.setBaseMileagePrice(new BigDecimal(form.getBaseMileagePrice()));
        orderBillEntity.setExceedMileagePrice(new BigDecimal(form.getExceedMileagePrice()));
        orderBillEntity.setBaseMinute(form.getBaseMinute());
        orderBillEntity.setExceedMinutePrice(new BigDecimal(form.getExceedMinutePrice()));
        orderBillEntity.setBaseReturnMileage(form.getBaseReturnMileage());
        orderBillEntity.setExceedReturnPrice(new BigDecimal(form.getExceedReturnPrice()));

        //传给服务层
        String orderId = orderService.insertOrder(orderEntity, orderBillEntity);

        return CommonResult.ok().put(CommonResult.RETURN_RESULT, orderId);
    }

    @PostMapping("/acceptNewOrder")
    @Operation(summary = "司机接单")
    public CommonResult acceptNewOrder(@Valid @RequestBody AcceptNewOrderForm form) {
        String result = orderService.acceptOrder(form.getOrderId(), form.getDriverId());
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, result);
    }

    @PostMapping("/searchDriverExecuteOrder")
    @Operation(summary = "查询司机正在执行的订单")
    public CommonResult searchDriverExecuteOrder(@Valid @RequestBody SearchDriverExecuteOrderForm form) {
        Map<String, Object> map = BeanUtil.beanToMap(form);
        HashMap hashMap = orderService.searchDriverExecuteOrder(map);
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, hashMap);
    }

    @PostMapping("/searchOrderStatus")
    @Operation(summary = "查询订单状态")
    public CommonResult searchOrderStatus(@Valid @RequestBody SearchOrderStatusForm form) {
        Map<String, Object> map = BeanUtil.beanToMap(form);
        Integer status = orderService.searchOrderStatus(map);
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, status);
    }

    @PostMapping("/deleteUnAcceptOrder")
    @Operation(summary = "删除未接受的订单")
    public CommonResult deleteUnAcceptOrder(@Valid @RequestBody DeleteUnAcceptOrderForm form) {
        Map<String, Object> map = BeanUtil.beanToMap(form);
        String result = orderService.deleteUnAcceptOrder(map);
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, result);
    }

    @PostMapping("/searchDriverCurrentOrder")
    @Operation(summary = "查询该司机当前正操作的订单")
    public CommonResult searchDriverCurrentOrder(@Valid @RequestBody SearchDriverCurrentOrderForm form) {
        HashMap hashMap = orderService.searchDriverCurrentOrder(form.getDriverId());
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, hashMap);
    }

    @PostMapping("/hasCustomerCurrentOrder")
    @Operation(summary = "是否有乘客当前订单未完成或还未接收")
    public CommonResult hasCustomerCurrentOrder(@Valid @RequestBody HasCustomerCurrentOrderForm form) {
        HashMap hashMap = orderService.hasCustomerCurrentOrder(form.getCustomerId());
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, hashMap);
    }

    @PostMapping("/searchOrderForMoveById")
    @Operation(summary = "查询订单信息用于司乘同显功能")
    public CommonResult searchOrderForMoveById(@Valid @RequestBody SearchOrderForMoveByIdForm form) {
        Map<String, Object> map = BeanUtil.beanToMap(form);
        HashMap hashMap = orderService.searchOrderForMoveById(map);
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, hashMap);
    }

    @PostMapping("/arriveStartPlace")
    @Operation(summary = "司机到达出发地")
    public CommonResult arriveStartPlace(@Valid @RequestBody ArriveStartPlaceForm form) {
        Map<String, Object> map = BeanUtil.beanToMap(form);
        //该方法是到达出发地 因此状态为3
        map.put("status", 3);
        int rows = orderService.arriveStartPlace(map);
        return CommonResult.ok().put(CommonResult.RETURN_ROW, rows);
    }

    @PostMapping("/confirmArriveStartPlace")
    @Operation(summary = "司机手动确认司机已到达出发地")
    public CommonResult confirmArriveStartPlace(@Valid @RequestBody ConfirmArriveStartPlaceForm form) {
        Boolean result = orderService.confirmArriveStartPlace(form.getOrderId());
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, result);
    }

    @PostMapping("/startDriving")
    @Operation(summary = "开始代驾")
    public CommonResult startDriving(@Valid @RequestBody StartDrivingForm form) {
        Map<String, Object> map = BeanUtil.beanToMap(form);
        map.put("status", 4);
        int rows = orderService.startDriving(map);
        return CommonResult.ok().put(CommonResult.RETURN_ROW, rows);
    }

    @PostMapping("/updateOrderStatus")
    @Operation(summary = "结束订单")
    public CommonResult updateOrderStatus(@Valid @RequestBody UpdateOrderStatusForm form) {
        Map<String, Object> map = BeanUtil.beanToMap(form);  //结束订单 这里的status由前端传递过来
        int rows = orderService.updateOrderStatus(map);
        return CommonResult.ok().put(CommonResult.RETURN_ROW, rows);
    }

    @PostMapping("/searchOrderByPage")
    @Operation(summary = "查询订单分页记录")
    public CommonResult searchOrderByPage(@Valid @RequestBody SearchOrderByPageForm form) {
        Map<String, Object> map = BeanUtil.beanToMap(form);
        Integer page = MapUtil.getInt(map, "page");
        Integer length = MapUtil.getInt(map, "length");
        Integer start = (page - 1) * length;
        map.put("start", start);
        PageUtils pageUtils = orderService.searchOrderByPage(map);
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, pageUtils);
    }

    @PostMapping("/searchOrderContent")
    @Operation(summary = "查询订单详细")
    public CommonResult searchOrderContent(@Valid @RequestBody SearchOrderContentForm form) {
        HashMap hashMap = orderService.searchOrderContent(form.getOrderId());
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, hashMap);
    }

    @PostMapping("/searchOrderStartLocationIn30Days")
    @Operation(summary = "查询30天内的代驾上车点坐标记录")
    public CommonResult searchOrderStartLocationIn30Days() {
        ArrayList<HashMap> hashMap = orderService.searchOrderStartLocationIn30Days();
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, hashMap);
    }

    @PostMapping("/validDriverOwnOrder")
    @Operation(summary = "查询是否是该司机的订单")
    public CommonResult validDriverOwnOrder(@RequestBody @Valid ValidDriverOwnOrderForm form) {
        Map map = BeanUtil.beanToMap(form);
        Boolean result = orderService.validDriverOwnOrder(map);
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, result);
    }

    @PostMapping("/searchSettlementNeedData")
    @Operation(summary = "查询一些必要的数据")
    public CommonResult searchSettlementNeedData(@RequestBody @Valid SearchSettlementNeedDataForm form) {
        HashMap hashMap = orderService.searchSettlementNeedData(form.getOrderId());
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, hashMap);
    }

    @PostMapping("/searchOrderById")
    @Operation(summary = "根据订单Id查询订单账单信息")
    public CommonResult searchOrderById(@RequestBody @Valid SearchOrderByIdForm form) {
        Map map = BeanUtil.beanToMap(form);
        HashMap resultMap =  orderService.searchOrderById(map);
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, resultMap);
    }
    @PostMapping("/validCanPayOrder")
    @Operation(summary = "查询该订单是否可支付")
    public CommonResult validCanPayOrder(@RequestBody @Valid ValidCanPayOrderForm form) {
        Map map = BeanUtil.beanToMap(form);
        HashMap resultMap =  orderService.validCanPayOrder(map);
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, resultMap);
    }
    @PostMapping("/updateOrderPrepayId")
    @Operation(summary = "更新订单预支付id")
    public CommonResult updateOrderPrepayId(@RequestBody @Valid UpdateOrderPrepayIdForm form) {
        Map map = BeanUtil.beanToMap(form);
        int rows =  orderService.updateOrderPrepayId(map);
        return CommonResult.ok().put("rows", rows);
    }

    @PostMapping("/receiveMessage")
    @Operation(summary = "接收微信平台的支付结果异步通知")
    public CommonResult receiveMessage(HttpServletRequest request , HttpServletResponse response) throws Exception {
        System.out.println("接收到了微信平台的支付结果通知");
        //获取微信平台返回的参数 防止接受的是乱码
        request.setCharacterEncoding("UTF-8");
        BufferedReader reader = request.getReader();
        String line = null;
        StringBuffer temp = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            temp.append(line);
        }
        reader.close();

        //拿到微信平台返回的参数xml格式 解析成map
        String xml = temp.toString();
        if (WXPayUtil.isSignatureValid(xml,wxPayConfig.getKey())) {
            //验证签名成功,参数没有被篡改 获取参数
            Map<String, String> map = WXPayUtil.xmlToMap(xml);
            System.out.println(map);
            String returnCode = map.get("return_code");
            String resultCode = map.get("result_code");
            if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
                //微信支付成功 通信成功且订单支付成功(业务成功) 则向微信平台返回响应代表我们接收到通知
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/xml");
                PrintWriter writer = response.getWriter();
                BufferedWriter bw = new BufferedWriter(writer);
                bw.write("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>");
                bw.close();

                //从map中获取必要参数
                String uuid = map.get("out_trade_no");
                String driverOpenId = map.get("attach");
                String payId = map.get("transaction_id");
                //转换支付时间
                String payTime = DateUtil.parse(map.get("time_end"), "yyyyMMddHHmmss").toString("yyyy-MM-dd HH:mm:ss");

                //TODO 修改订单状态 给司机发放系统奖励 分账相关
                orderService.handlePayment(uuid, driverOpenId, payId, payTime);
            }
        }else {
            response.sendError(500, "数字签命错误");
        }
        return null;
    }

    @PostMapping("/updateOrderAboutPayment")
    @Operation(summary = "乘客端主动向微信平台查询订单状态")
    public CommonResult updateOrderAboutPayment(@RequestBody @Valid UpdateOrderAboutPaymentForm form) {
        Map map = BeanUtil.beanToMap(form);
        String result = orderService.updateOrderAboutPayment(map);
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, result);
    }

    @PostMapping("/searchDriverOrderByPage")
    @Operation(summary = "查询司机订单列表分页记录")
    public CommonResult searchDriverOrderByPage(@RequestBody @Valid SearchDriverOrderByPageForm form) {
        Map map = BeanUtil.beanToMap(form);
        Integer page = MapUtil.getInt(map, "page");
        Integer length = MapUtil.getInt(map, "length");
        int start = (page - 1) * length;
        map.put("start", start);
        PageUtils pageUtils = orderService.searchDriverOrderByPage(map);
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, pageUtils);
    }

    @PostMapping("/searchCustomerOrderByPage")
    @Operation(summary = "查询乘客订单列表分页记录")
    public CommonResult searchCustomerOrderByPage(@RequestBody @Valid SearchCustomerOrderByPageForm form) {
        Map map = BeanUtil.beanToMap(form);
        Integer page = MapUtil.getInt(map, "page");
        Integer length = MapUtil.getInt(map, "length");
        int start = (page - 1) * length;
        map.put("start", start);
        PageUtils pageUtils = orderService.searchCustomerOrderByPage(map);
        return CommonResult.ok().put(CommonResult.RETURN_RESULT, pageUtils);
    }

}
